<template>
  <Layout class="template-layout-lc">
    <Sider class="layout-sider" hide-trigger :width="500">
      <Space direction="vertical" size="small" type="flex">
        <div class="sider-button">
          <Row>
            <Col span="20" style="display: inline-flex">
              <Select v-model="sysItem" size="default" @on-change="changeSys">
                <Option
                  v-for="item in sysList"
                  :value="item.value"
                  :key="item.value"
                  >{{ item.label }}</Option
                >
              </Select>
              <Button
                type="primary"
                size="default"
                class="ml-10"
                @click="addRoot"
                :loading="btnLoading"
                >添加一级菜单</Button
              >
              <Button
                type="error"
                size="default"
                class="ml-10"
                ghost
                @click="delBatch"
                :loading="btnLoading"
                >批量删除</Button
              >
            </Col>
            <Col span="4">
              <Icon
                type="ios-contract"
                :color="'#2d8cf0'"
                class="ml-5"
                @click="inExpandAllMenus"
              />
              <Icon
                type="ios-expand"
                :color="'#2d8cf0'"
                @click="expandAllMenus"
                class="ml-5"
              />
            </Col>
          </Row>
        </div>

        <Input
          icon="ios-search"
          placeholder="请输入关键字查询"
          size="default"
          style="width: 330px"
          v-model="menuTitle"
          @on-click="query"
        />
        <div class="tree-content">
          <Spin fix :show="loading">
            <Icon
              type="ios-loading"
              size="18"
              class="demo-spin-icon-load"
            ></Icon>
            <div>Loading</div>
          </Spin>
          <Tree
            ref="mTree"
            :data="menus"
            show-checkbox
            @on-contextmenu="handleContextMenu"
            @on-select-change="handleSelectChange"
          >
            <template #contextMenu>
              <DropdownItem @click="handleContextMenuAddSub"
                >添加下级菜单</DropdownItem
              >
              <DropdownItem
                @click="handleContextMenuDelete"
                style="color: #ed4014"
                >删除</DropdownItem
              >
            </template>
          </Tree>
        </div>
      </Space>
    </Sider>
    <Layout>
      <Content class="layout-content">
        <div class="form-spin">
          <Spin fix :show="!spinShow" size="large">
            <Icon
              type="ios-loading"
              size="30"
              class="demo-spin-icon-load"
            ></Icon>
            <!-- <div style="margin-top: 20px">请添加菜单...</div> -->
          </Spin>
          <zz-Form
            class="menu-form"
            ref="zzForm"
            title="菜单信息"
            :model="model"
            :rules="ruleValidate"
          >
            <Col span="12">
              <FormItem label="菜单名称" prop="title">
                <Input v-model="model.title" placeholder="请输入..."></Input>
              </FormItem>
            </Col>
            <Col span="24">
              <FormItem label="功能描述" prop="description">
                <Input
                  v-model="model.description"
                  placeholder="请输入..."
                ></Input>
              </FormItem>
            </Col>
            <Col span="24">
              <FormItem label="URL地址" prop="url">
                <Input
                  v-model="model.url"
                  placeholder="请输入..."
                  @on-blur="changeUrl"
                ></Input>
              </FormItem>
            </Col>
            <Col span="12">
              <FormItem label="节点排序" prop="displaySeq">
                <Input
                  v-model="model.displaySeq"
                  placeholder="请输入..."
                  type="number"
                ></Input>
              </FormItem>
            </Col>
            <Col span="12">
              <FormItem label="菜单类型" prop="menuType">
                <Select v-model="model.menuType" clearable>
                  <Option
                    v-for="item in menuTypeList"
                    :value="item.value"
                    :key="item.key"
                  >
                    {{ item.label }}
                  </Option>
                </Select>
              </FormItem>
            </Col>
            <Col span="12">
              <FormItem label="记录日志" prop="recordLog">
                <Select v-model="model.recordLog" clearable>
                  <Option
                    v-for="item in isRecordLog"
                    :value="item.value"
                    :key="item.key"
                  >
                    {{ item.label }}
                  </Option>
                </Select>
              </FormItem>
            </Col>
            <Col span="12">
              <FormItem label="菜单状态" prop="status">
                <Select v-model="model.status" clearable>
                  <Option
                    v-for="item in statusList"
                    :value="item.value"
                    :key="item.key"
                  >
                    {{ item.label }}
                  </Option>
                </Select>
              </FormItem>
            </Col>
            <Col span="12">
              <FormItem label="图标选择" prop="icon">
                <Input v-model="model.icon" placeholder="请输入..."></Input>
              </FormItem>
            </Col>
            <Col span="12">
              <FormItem label="上级节点" prop="parentName">
                <Input
                  v-model="model.parentName"
                  placeholder="无上级..."
                  disabled
                ></Input>
              </FormItem>
            </Col>
          </zz-Form>
          <div class="form-button">
            <Button
              type="primary"
              size="default"
              class="ml-10"
              @click="add"
              :loading="btnLoading"
              :disabled="!spinShow"
              >保存</Button
            >
            <Button
              type="primary"
              size="default"
              class="ml-10"
              ghost
              @click="reset"
              :loading="btnLoading"
              :disabled="!spinShow"
              >重置</Button
            >
          </div>
        </div>
      </Content>
    </Layout>
  </Layout>
</template>

<script>
export default {
  name: 'menuManagement',
  components: {},
  data() {
    const validateSequence = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入节点排序...'))
      } else if (!Number.isInteger(+value)) {
        callback(new Error('输入数字'))
      } else {
        callback()
      }
    }
    return {
      // model
      model: {
        title: '',
        description: '',
        url: '',
        displaySeq: 0,
        menuType: '',
        recordLog: '',
        status: '',
        icon: '',
        parentId: '',
        parentName: '',
      },
      menuTitle: '',
      // list
      menuTypeList: [],
      isRecordLog: [],
      statusList: [],
      // 页面显示相关
      loading: false,
      btnLoading: false,
      spinShow: false,
      // 业务相关
      menus: [],
      contextData: {},
      sysList: [
        { value: 'zz-admin', label: 'zz-admin' },
        { value: 'zz-pda', label: 'zz-pda' },
      ],
      sysItem: 'zz-admin',
      ruleValidate: {
        title: [
          {
            required: true,
            message: '菜单名称不能为空...',
            trigger: 'change',
          },
        ],
        url: [
          {
            required: true,
            message: 'url不能为空...',
            trigger: 'change',
          },
        ],
        displaySeq: [
          {
            required: true,
            validator: validateSequence,
            trigger: 'change',
          },
        ],
      },
    }
  },
  computed: {},
  created() {
    this.init()
    this.query()
  },
  methods: {
    // 初始化
    init() {
      this.menuTypeList = [
        { key: '1', value: '1', label: '管理型' },
        { key: '2', value: '2', label: '业务型' },
      ]
      this.isRecordLog = [
        { key: '1', value: '1', label: '是' },
        { key: '2', value: '0', label: '否' },
      ]
      this.statusList = [
        { key: '1', value: '1', label: '生效' },
        { key: '2', value: '0', label: '失效' },
      ]
    },
    // 查询
    async query() {
      this.loading = true
      let param = {
        title: this.menuTitle,
        useSys: this.sysItem,
      }
      let res = await this.$API.menuManagement.menu.queryByMenuName.post(param)
      if (res.code === '01') {
        this.menus = res.data
        // 自动展开
        this.expandAllMenus()
        this.loading = false
      } else {
        this.loading = false
      }
    },
    changeSys() {
      this.reset()
      this.spinShow = false
      this.menuTitle = ''
      this.query()
    },
    handleContextMenu(data) {
      this.contextData = data
    },
    handleContextMenuAddSub() {
      this.spinShow = true
      this.reset()
      this.model.parentId = this.contextData.menuId
      this.model.parentName = this.contextData.title
      this.model.menuType = '1'
      this.model.recordLog = '0'
      this.model.status = '1'
    },
    async handleContextMenuDelete() {
      this.$Modal.confirm({
        title: '确认',
        content: '确定要删除吗？',
        onOk: async () => {
          this.btnLoading = true
          let res = await this.$API.menuManagement.menu.delete.get(
            this.contextData.menuId
          )
          if (res.code === '01') {
            this.$Message.success('删除成功')
            this.btnLoading = false
            this.reset()
            this.query()
          } else {
            this.$Message.error(res.message)
            this.btnLoading = false
          }
        },
      })
    },
    // 点击菜单
    handleSelectChange(data) {
      if (data == null || data.length == 0) {
        return
      }
      this.spinShow = true
      // 单选返回 => obj
      let obj = data[0]
      let pMenu = {}
      if (obj.parentId) {
        pMenu = this.queryById(obj.parentId)
      }

      this.model = JSON.parse(JSON.stringify(obj))
      this.model.parentName = pMenu?.title
      this.model.url = obj.url.replace('/index.vue', '')

      this.model.recordLog = '0'
      this.model.status = '1'
    },
    expandAllMenus() {
      let that = this
      this.menus.forEach((menu) => {
        that.setExpandStatus(menu, true)
      })
    },

    inExpandAllMenus() {
      this.menus.forEach((menu) => {
        this.setExpandStatus(menu, false)
      })
    },
    setExpandStatus(menu, status) {
      menu.expand = status
      menu.contextmenu = true
      if (menu.children) {
        menu.children.forEach((child) => {
          this.setExpandStatus(child, status)
        })
      }
    },
    // 新增一级菜单
    addRoot() {
      this.spinShow = true
      this.reset()
      this.model.menuType = '1'
      this.model.recordLog = '0'
      this.model.status = '1'
    },
    // 新增或编辑
    async add() {
      let valid = await this.$refs.zzForm.validate()
      if (!valid) {
        return
      }
      this.btnLoading = true
      let param = this.dealParams()
      if (this.model.menuId) {
        let res = await this.$API.menuManagement.menu.modify.post(param)
        if (res.code === '01') {
          this.$Message.success('修改成功')
          this.btnLoading = false
          this.reset()
          this.query()
        } else {
          this.$Message.error(res.message)
          this.btnLoading = false
        }
      } else {
        let res = await this.$API.menuManagement.menu.save.post(param)
        if (res.code === '01') {
          this.$Message.success('保存成功')
          this.btnLoading = false
          this.reset()
          this.query()
        } else {
          this.$Message.error(res.message)
          this.btnLoading = false
        }
      }
    },
    // 组装参数
    dealParams() {
      let params = {
        ...this.model,
      }

      params.menuName = this.getMenuName(this.model.url)
      params.path = this.getPath(this.model.url)
      params.useSys = this.sysItem
      this.$TOOL.removeEmptyProperties(params)
      return params
    },
    // 更改url
    changeUrl() {},
    // 批量删除
    async delBatch() {
      let checkedMenus = this.$refs.mTree.getCheckedNodes()
      // 校验
      if (checkedMenus.length === 0) {
        this.$Message.warning('请选择要删除的数据')
        return
      }
      this.$Modal.confirm({
        title: '确认',
        content: '确定要删除吗？',
        onOk: async () => {
          let menuIds = checkedMenus.map((e) => e.menuId)
          let res = await this.$API.menuManagement.menu.deleteBatch.post(
            menuIds
          )
          if (res.code === '01') {
            this.$Message.success('批量删除成功')
            this.btnLoading = false
            this.reset()
            this.query()
          } else {
            this.$Message.error(res.message)
            this.btnLoading = false
          }
        },
      })
    },
    // 重置
    reset() {
      this.$refs.zzForm.resetFields()
      this.model = {
        title: '',
        description: '',
        url: '',
        displaySeq: 0,
        type: '',
        recordLog: '',
        status: '',
        icon: '',
        parentId: '',
        parentName: '',
      }
    },
    // 通過id查找菜單
    queryById(id) {
      let menusList = this.$XEUtils.toTreeArray(this.menus)
      return menusList.find((e) => e.menuId === id)
    },
    // 处理url => menuName
    getMenuName(str) {
      let segments = str.split('/')
      let lastSegment = segments[segments.length - 1]
      let capitalizedLastSegment =
        lastSegment.charAt(0).toUpperCase() + lastSegment.slice(1)
      return capitalizedLastSegment
    },
    // 处理url => path
    getPath(str) {
      let segments = str.split('/')
      let lastSegment = segments[segments.length - 1]
      return '/' + lastSegment
    },
  },
}
</script>

<style lang="less" scoped>
/* 选择框样式 */
:deep(.ivu-select-selection) {
  border-radius: 10px;
  font-size: 13px;
  height: 30px;
  line-height: 30px;
}

.sider-button {
  margin-top: 10px;
  width: 100%;
}
.form-button {
  display: flex;
  justify-content: flex-end;
  padding-right: 30px;
}
.menu-form {
  margin: 30px;
}
:deep(.main-form-box .ivu-form-item-label) {
  font-size: 13px;
}
:deep(.main-form-box .box-title) {
  font-size: 13px;
}
:deep(.main-form-box .ivu-input-small) {
  font-size: 13px;
}
.tree-content {
  height: calc(100vh - 220px);
  overflow: auto;
}
:deep(.demo-spin-icon-load) {
  animation: ani-demo-spin 1s linear infinite;
}
.sider-button .ivu-select {
  width: auto;
}
.form-spin {
  position: relative;
}
.form-spin .ivu-spin-fix {
  margin-top: -30.8px;
  background-color: rgba(255, 255, 255, 0.4);
}
</style>
